package cn.ulc.socket.admin.service.site.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.ulc.common.constant.PubDataConstant;
import cn.ulc.common.constant.enums.AvailableStatus;
import cn.ulc.common.constant.enums.DeletedStatus;
import cn.ulc.common.exception.PlatformException;
import cn.ulc.common.model.param.PaginationParam;
import cn.ulc.socket.admin.common.BaseService;
import cn.ulc.socket.admin.model.dto.site.CityListDTO;
import cn.ulc.socket.admin.model.dto.site.SiteDTO;
import cn.ulc.socket.admin.model.dto.site.SiteListDTO;
import cn.ulc.socket.admin.model.param.site.SiteParam;
import cn.ulc.socket.admin.service.site.SiteServ;
import cn.ulc.store.dao.CitysDao;
import cn.ulc.store.dao.PubDataDao;
import cn.ulc.store.dao.site.SiteDao;
import cn.ulc.store.dao.site.SiteRegionDao;
import cn.ulc.store.dao.staff.StaffDao;
import cn.ulc.store.dao.staff.StaffRoleDao;
import cn.ulc.store.entity.Citys;
import cn.ulc.store.entity.Company;
import cn.ulc.store.entity.site.Site;
import cn.ulc.store.entity.site.SiteRegion;
import cn.ulc.store.entity.staff.Staff;
import cn.ulc.store.entity.staff.StaffRole;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 分站信息
 */
@Service
@AllArgsConstructor
public class SiteServImpl extends BaseService implements SiteServ {
    private static final Log log = LogFactory.get();


    SiteDao siteDao;
    CitysDao citysDao;
    StaffDao staffDao;
    StaffRoleDao staffRoleDao;
    PubDataDao pubDataDao;
    SiteRegionDao siteRegionDao;
    @Override
    public SiteListDTO findList(String key,String cityCode,PaginationParam param) {
        Company company = getCurrentCompany();
        Map<String,Object> condition = new HashMap<>();
        condition.put("companyId",company.getId());
        condition.put("key",key);
        condition.put("city", cityCode);
        PageQuery pageQuery = initPageQuery(param);
        pageQuery.setParas(condition);
        siteDao.findListPage(pageQuery);
        return new SiteListDTO(pageQuery.getList(),pageQuery.getTotalRow());
    }

    @Override
    public SiteDTO findDetail(Long id) {
        Site entity = siteDao.findById(id);
        return new SiteDTO(entity);
    }

    @Override
    @Transactional
    public Boolean save(SiteParam param) {
        Company company = getCurrentCompany();
        Site entity = new Site();
        setBaseInfo(entity);
        entity.setCompanyId(company.getId());
        entity.setName(param.getName());
        entity.setStaffId(param.getStaffId());
        entity.setCity(param.getCity());
        entity.setCityName(param.getCityName());
        entity.setProvince(param.getProvince());
        entity.setProvinceName(param.getProvinceName());
        entity.setStatus(AvailableStatus.AVAILABLE);
        Site defaultSite = siteDao.findDefault(company.getId());
        if(defaultSite!=null){
            entity.setIsDefault(false);
        }else{
            entity.setIsDefault(true);
        }
        siteDao.save(entity);
        Staff staff = staffDao.findOne(param.getStaffId());
        String code = pubDataDao.findCodeByTypeAndName(PubDataConstant.DATA_TYPE_ROLE,"站长");
        if(staff!=null && StringUtils.isNotBlank(code)){
            StaffRole staffRole = staffRoleDao.findByRole(staff.getId(),code);
            if(staffRole==null){
                staffRole = new StaffRole();
                setBaseInfo(staffRole);
                staffRole.setStaffId(staff.getId());
                staffRole.setRole(code);
                staffRole.setRoleName("站长");
                staffRole.setCompanyId(company.getId());
                staffRoleDao.save(staffRole);
            }
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean update(Long id, SiteParam param) {
        Company company = getCurrentCompany();
        Site site = siteDao.findOne(id);
        if(site==null) throw new PlatformException("获取分站信息失败!");
        site.setName(param.getName());
        if(!site.getCity().equals(param.getCity())){
            Site checkCity = siteDao.findByCity(company.getId(),param.getCity());
            if(checkCity!=null) throw new PlatformException("该地区已建立分站");
            List<SiteRegion> regionList = siteRegionDao.findBySiteId(site.getId());
            if(regionList.size()>0) throw new PlatformException("该分站下存在区域不能修改分站地址");
            site.setCity(param.getCity());
            site.setCityName(param.getCityName());
            site.setProvince(param.getProvince());
            site.setProvinceName(param.getProvinceName());
        }
        if(site.getStaffId().intValue()!=param.getStaffId().intValue()){
            site.setStaffId(param.getStaffId());
            String code = pubDataDao.findCodeByTypeAndName(PubDataConstant.DATA_TYPE_ROLE,"站长");
            if(StringUtils.isNotBlank(code)){
                StaffRole staffRole = staffRoleDao.findByRole(site.getStaffId(),code);
                staffRole.setDeleted(DeletedStatus.DELETED);
                staffRoleDao.save(staffRole);
                StaffRole newStaffRole = new StaffRole();
                setBaseInfo(newStaffRole);
                newStaffRole.setStaffId(param.getStaffId());
                newStaffRole.setRole(code);
                newStaffRole.setRoleName("站长");
                newStaffRole.setCompanyId(company.getId());
                staffRoleDao.save(newStaffRole);
            }
        }
        siteDao.save(site);
        return true;
    }

    @Override
    @Transactional
    public Long delete(Long id) {
        Site site = siteDao.findOne(id);
        if(site == null) throw new PlatformException("押金退款订单明细已不存在");
        List<SiteRegion> regionList = siteRegionDao.findBySiteId(site.getId());
        if(regionList.size()>0) throw new PlatformException("该分站下存在区域不能删除分站");
        //删除站长
        String code = pubDataDao.findCodeByTypeAndName(PubDataConstant.DATA_TYPE_ROLE,"站长");
        if(StringUtils.isNotBlank(code)){
            StaffRole role = staffRoleDao.findByRole(site.getStaffId(),code);
            if(role!=null){
                setBaseInfo(role);
                role.setDeleted(DeletedStatus.DELETED);
                staffRoleDao.save(role);
            }
        }
        site.setDeleted(DeletedStatus.DELETED);
        setBaseInfo(site);
        siteDao.save(site);
        return id;
    }

    @Override
    public CityListDTO findCityList() {
        List<Citys> cityList = citysDao.findCityList();
        List<Citys> resultList = new ArrayList<>();
        if(cityList!=null && cityList.size() >0){
            Map<Long,List<Citys>> cityMap = cityList.stream().collect(Collectors.groupingBy(Citys::getParentId));
            if(cityMap.get(1l)!=null && cityMap.get(1l).size()>0){
                resultList = cityMap.get(1l);
                resultList.stream().forEach(t->{
                    t.setChildren(cityMap.get(t.getId()));
                });
            }
        }
        return new CityListDTO(resultList);
    }



    @Override
    public Boolean changeStatus(Long id, AvailableStatus status) {
        Site site = siteDao.findOne(id);
        if(site==null) throw new PlatformException("获取分站信息失败!");
        setBaseInfo(site);
        site.setStatus(status);
        siteDao.save(site);
        return true;
    }

    @Override
    @Transactional
    public Boolean changeDefault(Long id) {
        Company company = getCurrentCompany();
        Site site = siteDao.findOne(id);
        if(site==null) throw new PlatformException("获取分站信息失败!");
        Site defaultSite = siteDao.findDefault(company.getId());
        if(defaultSite!=null){
            setBaseInfo(defaultSite);
            defaultSite.setIsDefault(false);
            siteDao.save(defaultSite);
        }
        setBaseInfo(site);
        site.setIsDefault(true);
        siteDao.save(site);
        return true;
    }
}
